/**
 * Copyright (c) 2016-2020 https://github.com/zhaohuatai
 *
 * contact z_huatai@qq.com
 *  
 */
package org.zfes.snowy.auth.shiro.session.repository.impl;

import org.apache.shiro.session.Session;
import org.springframework.util.CollectionUtils;
import org.zfes.snowy.auth.shiro.session.repository.IShiroSessionRepository;
import org.zfes.snowy.common.nosql.redis.jedis.SnowyJedisManager;
import org.zfes.snowy.core.exceptions.AppRuntimeException;
import org.zfes.snowy.core.util.ZSerialUtil;

import com.google.common.collect.Lists;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * ShiroSession Jedis形式实现类，
 * <br>session存储用redis db0  索引，注意后续使用不要随意占用
* @ClassName :JedisShiroSessionRepository     
* @Description :   
* @createTime :2015年5月7日  上午9:38:33   
* @author ：zhaohuatai   
* @version :1.0
 */

public class RedisShiroSessionRepository implements IShiroSessionRepository {
	
	private static final String REDIS_SHIRO_SESSION = "ss";
    private static final int SESSION_VAL_TIME_SPAN = 18000;
    private static final int DB_INDEX = 0;

    private SnowyJedisManager jedisManager;
    

    
    
    @Override
    public void saveSession(Session session) {
        if (session == null || session.getId() == null)
            throw new NullPointerException("session is empty");
        try {
            long sessionTimeOut = session.getTimeout() / 1000;
            Long expireTime = sessionTimeOut + SESSION_VAL_TIME_SPAN + (5 * 60);
            //2分钟后删除redis数据
//            Long expireTime = sessionTimeOut  + (2 * 60);
            //30s后删除redis数据
//            Long expireTime = sessionTimeOut  + (30);
            jedisManager.stringForObjSet(addPrefix(session.getId()), session, expireTime.intValue());
            
        } catch (Exception e) {
        	throw new AppRuntimeException(e);
        }
    }

    @Override
    public void deleteSession(String id) {
        if (id == null) {
            throw new NullPointerException("session id is empty");
        }
        try {
        	jedisManager.delBinary(addPrefix(id));
        } catch (Exception e) {
        	throw new AppRuntimeException(e);
        }
    }
    
    @Override
    public void updateSession(Session session) {
        if (session == null || session.getId() == null)
            throw new NullPointerException("session is empty");
        try {
        	  long sessionTimeOut = session.getTimeout() / 1000;
              Long expireTime = sessionTimeOut + SESSION_VAL_TIME_SPAN + (5 * 60);
        	jedisManager.stringForObjSet(addPrefix(session.getId()), session, expireTime.intValue());
        } catch (Exception e) {
        	throw new AppRuntimeException(e);
        }
    }
    
    @Override
    public Session getSession(String id) {
        if (id == null){
        	 throw new NullPointerException("session id is empty");
        }
        Session session = null;
        try {
        	session =(Session)jedisManager.stringForObjGet(addPrefix(id));
        } catch (Exception e) {
        	throw new AppRuntimeException(e);
        }
        return session;
    }

    @Override
    public Collection<Session> getAllSessions() {
           try {
        	 //  Set<String>  keys =jedisManager.keysBinary("*"+REDIS_SHIRO_SESSION + "*");
        	   Set<String>  keys =jedisManager.keys("*"+REDIS_SHIRO_SESSION + "*");
        	   List<Session> values = Lists.newArrayList();
        	   if (!CollectionUtils.isEmpty(keys)) {
        		   for (String key : keys) {
        			   Session session =(Session)jedisManager.stringForObjGet(key);
        			   if (session != null) {
                           values.add(session);
                       }
        		   }
        	   }
        	   return Collections.unmodifiableList(values);
           } catch (Exception t) {
        	   throw new AppRuntimeException(t);
           }
    }

    public SnowyJedisManager getJedisManager() {
        return jedisManager;
    }

    public void setJedisManager(SnowyJedisManager jedisManager) {
        this.jedisManager = jedisManager;
    }
    private String addPrefix(Serializable sessionId) {
        return REDIS_SHIRO_SESSION+":" + sessionId;
    }
}
